<script setup lang="ts">
import Border from "@/components/Border.vue";
import {onWatcherCleanup, reactive, ref, watch, watchEffect} from "vue";
import Card from "@/components/Card.vue";
import {NButton} from "naive-ui";


let msg = "hello world";
const msg2 = ref('');

const question = ref('');
const answer = ref('');
const loading = ref(false);
const area = [
  {id: '440303', name: '罗湖区'},
  {id: '440304', name: '福田区'},
  {id: '440305', name: '南山区'},
  {id: '440306', name: '宝安区'},
  {id: '440307', name: '龙岗区'},
  {id: '440308', name: '盐田区'},
  {id: '440309', name: '龙华区'},
  {id: '440310', name: '坪山区'},
  {id: '440311', name: '光明区'},
  {id: '441581', name: '陆丰'},
  {id: '440100', name: '广州'},
];
const cityCode = ref('');
const result = ref<Array<Weather>>([]);

//定义一个侦听器
watch(cityCode, async (value, oldValue) => {
  console.log(value)
  console.log(oldValue)
  loading.value = true;
  answer.value = '思考中...'
  result.value = [];
  try {
    const key = '2f02a3b9f0176753d5f5ddacc430dc5f';
    const url = `https://restapi.amap.com/v3/weather/weatherInfo?key=${key}&city=${cityCode.value}&extensions=all`;
    const request = await fetch(url);
    const ret = await request.json();
    answer.value = (ret.forecasts)[0].casts;
    result.value = (ret.forecasts)[0].casts;
    console.log(result.value)
  } catch (e) {
    answer.value = `error:${e}`;
  } finally {
    loading.value = false;
  }
});

const obj = reactive({count: 1});
const objDeep = reactive({count: 1});
const objOnce = reactive({count: 1});

const city = ref('');


//监听器
// 第一个参数，监听对象，它可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数(带返回对象属性的箭头函数)、或多个数据源组成的数组
// 第二个参数，回调函数 (newValue,oldValue)=>{}
// 第三个参数，配置参数


// 普通监听器--整个响应式对象
watch(obj, (value, oldValue) => {//注意：`newValue` 此处和 `oldValue` 是相等的,因为它们是同一个对象！
  console.log(`newValue: ${value.count} oldValue: ${oldValue.count}`);
})

//深层监听器--响应式对象的 某个属性
watch(() => objDeep.count, (newValue, oldValue) => {
  console.info(`深层监听器 new value ${newValue}, oldValue: ${oldValue}`);
}, {deep: true})//watch 第三个参数，可以强制转成深层侦听器

//即时回调的侦听器-建侦听器时，立即执行一遍回调
//默认是懒执行的：仅当数据源变化时，才会执行回调
//第三参数:{ immediate: true } 强制侦听器的回调立即执行
const ojbIm = reactive({count: 0})
watch(() => ojbIm.count, (newValue, oldValue) => {
  console.info('即时回调的侦听器', newValue);

}, {immediate: true}) //ojbIm.count初始0，
//一次性监听器
watch(() => objOnce.count, (newValue, oldValue) => {
  console.info('一次性监听器', newValue);
}, {once: true,/**一次性监听器**/})

const weather = ref<Array<Weather>>([]);
const weatherLoading = ref(false);

interface Weather {
  date: string,
  daypower: string,
  daytemp: string,
  dayweather: string,
  daywind: string,
  nightpower: string,
  nighttemp: string,
  nightweather: string,
  nightwind: string,
}

//
watchEffect(async () => {
  weatherLoading.value = true;
  try {
    const key = '2f02a3b9f0176753d5f5ddacc430dc5f';
    const url = `https://restapi.amap.com/v3/weather/weatherInfo?key=${key}&city=${city.value}&extensions=all`;
    const request = await fetch(url);
    const ret = await request.json();
    weather.value = (ret.forecasts)[0].casts;
  } catch (e) {
    // weather.value = `error:${e}`;
    console.error(e);
  } finally {
    weatherLoading.value = false;
  }
  onWatcherCleanup(() => {
    // 终止过期请求

  })

})


</script>

<template>
  <border>
    <p>非响应式</p>
    <p>{{ msg }}</p>
    <input type="text" v-model="msg">
    <p>响应式</p>
    <p>{{ msg2 }}</p>
    <input type="text" v-model="msg2">
  </border>
  <card title="侦听器">
    <p>侦听整个响应式对象</p>
    选择区：
    <select v-model="cityCode" :disabled="loading">
      <option disabled value="">--请选择--</option>
      <option v-for="(item,idx) of area" :value="item.id">{{ item.name }}</option>
    </select>
    <p>天气预报</p>
    <div>{{ answer }}</div>
    <div>
      <p v-for="(item,idx) of result">{{ item.date }}
        白天风力{{ item.daypower }}级，气温{{ item.daytemp }}度，{{ item.dayweather }} {{ item.daywind }}风
        ，晚上风力{{ item.nightpower }}级，气温{{ item.nighttemp }}度，{{ item.nightweather }} {{ item.nightwind }}风
      </p>
    </div>
  </card>
  <card title="普通监听器">
    <p>侦听响应式对象的属性值</p>
    <p>点击数：{{ obj.count }}</p>
    <n-button @click="obj.count++">点击</n-button>
  </card>
  <card title="深层侦听器">
    <p>点击数：{{ objDeep.count }}</p>
    <n-button @click="objDeep.count++">点击</n-button>
  </card>
  <card title="即时回调的侦听器">
    <p>点击数：{{ ojbIm.count }}</p>
    <n-button @click="ojbIm.count++">点击</n-button>
  </card>
  <card title="一次性侦听器">
    <p>点击数：{{ objOnce.count }}</p>
    <n-button @click="objOnce.count++">点击</n-button>
  </card>
  <card title="watchEffect">
    <p>watchEffect可以作用域内所有响应式变量加入监听列表</p>
    <p>watch需要定义一个监听列表</p>
    <p>value:{{ city }}</p>
    <select v-model="city" :disabled="weatherLoading">
      <option disabled value="">--请选择--</option>
      <option v-for="(item,idx) of area" :value="item.id">{{ item.name }}</option>
    </select>
    <!--    <p v-for="(item,idx) of weather">{{item.date}} {{item.dayweather}}/{{item.nightweather}}, {{item.daytemp_float}}/{{item.nighttemp_float}}， {{item.daywind}}风 {{item.daypower}}级 {{item.nightwind}}风/{{item.nightwind}}风 {{item.nightpower}}级</p>-->


  </card>
</template>

<style scoped>

</style>